package com.yc.navy.springmvc.core;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.bind.annotation.RequestParam;

import com.yc.navy.springmvc.util.StringUtil;

public class HandlerRequest {
	
	public static Object[] handle(HttpServletRequest req, HttpServletResponse resp,  Method method) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
		int count = method.getParameterCount();
		if(count == 0) {	//说明这个方法不需要参数
			return null;
		}
		Object[] args = new Object[count];
		Parameter[] params = method.getParameters();
		
		String paramName;
		String value = null;
		int index = 0;
		Class<?> cls = null;
		RequestParam requestParam;
		Map<String, String[]> paramValues = null;
		Map<String, Object> paramMap = null;
		String[] arrs = null;
		Field[] fields = null;
		Object obj = null;
		String attrName = null;
		Class<?> attrType = null;
		
		//遍历形参列表从请求中获取值-》有没有@RequestParam注解
		for(Parameter param : params) {
			paramName = param.getName();
			cls = param.getType();
			// 根据形参名从请求中获取值->有没有@RequestParam
			requestParam = param.getAnnotation(RequestParam.class);
			if(requestParam != null) {
				paramName = requestParam.value();	
			}
			value = req.getParameter(paramName);
			//判断请求的类型
			if(cls == Integer.TYPE) {
				args[index ++] = Integer.parseInt(value);
				continue;
			}
			
			if(cls == Integer.class) {
				args[index ++] = Integer.valueOf(value);
				continue;
			}
			
			if(cls == Double.TYPE) {
				args[index ++] = Double.parseDouble(value);
				continue;
			}
			
			if(cls == Double.class) {
				args[index ++] = Double.valueOf(value);
				continue;
			}
			
			if(cls == Long.TYPE) {
				args[index ++] = Long.parseLong(value);
				continue;
			}
			
			if(cls == Long.class) {
				args[index ++] = Long.valueOf(value);
				continue;
			}
			
			if(cls == String.class) {
				args[index ++] = value;
				continue;
			}
			
			//
			if(cls == Map.class || cls == HashMap.class) {
				paramValues = req.getParameterMap();
				paramMap = new HashMap<String, Object>();
				for(Entry<String,String[]> entry : paramValues.entrySet()) {
					arrs = entry.getValue();
					if(arrs != null && arrs.length == 1) {
						paramMap.put(entry.getKey(), arrs[0]);
						continue;
					}
					paramMap.put(entry.getKey(), Arrays.toString(arrs));
				}
				args[index++] = paramMap;
				continue;
			}
			
			if(cls == HttpServletRequest.class || cls == ServletRequest.class) {
				args[index++] = paramMap;
				continue;
			}
			
			if(cls == HttpServletRequest.class || cls == ServletRequest.class) {
				args[index++] = req;
				continue;
			}
			
			if(cls == HttpServletRequest.class || cls == ServletRequest.class) {
				args[index++] = resp;
				continue;
			}
			
			if(cls == HttpSession.class) {
				args[index++] = req.getSession();
				continue;
			}
			
			if(cls == ServletContext.class) {
				args[index ++] = req.getServletContext();
				continue;
			}
			//当成自定义对象处理
			fields = cls.getDeclaredFields();//获取所有的字段
			if(fields == null || fields.length <= 0) {
				args[index ++] = null;
				continue;
			}
			
			obj = cls.getConstructor().newInstance();

			//循环所有字段，并给这些字段住址
			for(Field fd : fields) {
				fd.setAccessible(true);
				attrName = fd.getName();
				attrType = fd.getType();
				value = req.getParameter(attrName);
				
				if(StringUtil.checkNull(value)) {
					continue;
				}
				
				if(attrType == Integer.TYPE) {
					fd.set(obj, Integer.parseInt(value));
					continue;
				}
				
				if(attrType == Integer.class) {
					fd.set(obj, Integer.valueOf(value));
					continue;
				}
				
				if(attrType == Double.TYPE) {
					fd.set(obj, Double.parseDouble(value));
					continue;
				}
				
				if(attrType == Double.class) {
					fd.set(obj, Double.valueOf(value));
					continue;
				}
				
				if(attrType == Long.TYPE) {
					fd.set(obj, Long.parseLong(value));
					continue;
				}
				
				if(attrType == Long.class) {
					fd.set(obj, Long.valueOf(value));
					continue;
				}
				fd.set(obj, value);
			}
			args[index ++] = obj;
			//session
			
			//request
			
			//response
			
			//application
			
		}
		System.out.println(Arrays.toString(args));
		return args;	
	}
}
